package com.enation.app.javashop.core.base.service.impl;

import com.enation.app.javashop.core.base.model.dos.EmailDO;
import com.enation.app.javashop.core.base.model.vo.EmailVO;
import com.enation.app.javashop.core.base.rabbitmq.AmqpExchange;
import com.enation.app.javashop.core.base.service.EmailManager;
import com.enation.app.javashop.core.system.SystemErrorCode;
import com.enation.app.javashop.core.system.model.dos.SmtpDO;
import com.enation.app.javashop.core.system.service.SmtpManager;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.logs.Debugger;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Date;
import java.util.Properties;

/**
 * 邮件发送实现
 *
 * @author zh
 * @version v7.0
 * @since v7.0
 * 2018年3月26日 下午3:23:04
 */
@Service
public class EmailManagerImpl implements EmailManager {
    @Autowired
    private SmtpManager smtpManager;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private Debugger debugger;

    @Autowired
    @Qualifier("systemDaoSupport")
    private DaoSupport systemDaoSupport;

    /**
     * 通过java Transport发送邮件  支持ssl
     *
     * @param emailVO
     */
    @Override
    public void sendMailByTransport(SmtpDO smtp, EmailVO emailVO) {

        try {
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
            //设置邮件会话参数
            Properties props = new Properties();
            //邮箱的发送服务器地址
            props.setProperty("mail.smtp.host", smtp.getHost());
            //邮箱发送服务器端口,这里设置为465端口
            props.setProperty("mail.smtp.port", String.valueOf(smtp.getPort()));
            props.setProperty("mail.transport.protocol", "smtp");
            props.put("mail.smtp.auth", "true");
            props.setProperty("mail.smtp.socketFactory.port", String.valueOf(smtp.getPort()));
            props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
            props.setProperty("mail.smtp.socketFactory.fallback", "false");

            final String username = smtp.getUsername();
            final String password = smtp.getPassword();
            //获取到邮箱会话,利用匿名内部类的方式,将发送者邮箱用户名和密码授权给jvm
            Session session = Session.getDefaultInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

            // 创建邮件发送者地址
            Address from = new InternetAddress(smtp.getUsername(), smtp.getMailFrom());

            //通过会话,得到一个邮件,用于发送
            Message msg = new MimeMessage(session);
            //设置发件人
            msg.setFrom(new InternetAddress(emailVO.getEmail()));

            // 设置邮件消息的发送者
            msg.setFrom(from);

            Address to = new InternetAddress(emailVO.getEmail());
            //设置收件人,to为收件人
            msg.setRecipient(Message.RecipientType.TO, to);
            // 设置邮件消息的主要内容
            msg.setContent(emailVO.getContent(), "text/html;charset=utf-8");
            //设置邮件消息
            msg.setSubject(emailVO.getTitle());
            //设置发送的日期
            msg.setSentDate(new Date());


            //调用Transport的send方法去发送邮件
            Transport.send(msg);

        } catch (Exception e) {
            debugger.log("邮件发送失败:", StringUtil.getStackTrace(e));
            e.printStackTrace();
            emailVO.setErrorNum(1);
            emailVO.setSuccess(0);
            throw new ServiceException(SystemErrorCode.E904.code(), "邮件发送失败！");
        }

        emailVO.setErrorNum(0);
        emailVO.setSuccess(1);
        //向库中插入
        this.add(emailVO);

    }

    /**
     * 通过javamail 发送邮件 暂不支持ssl
     *
     * @param emailVO
     */
    @Override
    public void sendMailByMailSender(SmtpDO smtp, EmailVO emailVO) {
        //否则使用javaMailSender
        JavaMailSender javaMailSender = new JavaMailSenderImpl();

        ((JavaMailSenderImpl) javaMailSender).setHost(smtp.getHost());
        ((JavaMailSenderImpl) javaMailSender).setUsername(smtp.getUsername());
        ((JavaMailSenderImpl) javaMailSender).setPassword(smtp.getPassword());
        ((JavaMailSenderImpl) javaMailSender).setPort(smtp.getPort());
        //设置发送者
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

            //设置邮件标题
            helper.setSubject(emailVO.getTitle());
            //设置邮件内容
            helper.setText(emailVO.getContent());

            //设置邮件 收件人
            helper.setTo(emailVO.getEmail());

            helper.setFrom(smtp.getMailFrom());
            //发送邮件
            javaMailSender.send(message);
            debugger.log("邮件发送成功");

        } catch (Exception e) {
            debugger.log("邮件发送失败:", StringUtil.getStackTrace(e));

            e.printStackTrace();
            emailVO.setErrorNum(1);
            emailVO.setSuccess(0);
            throw new ServiceException(SystemErrorCode.E904.code(), "邮件发送失败！");
        }
        //向库中插入
        this.add(emailVO);
    }



    /**
     * 添加发邮件记录
     *
     * @param email 邮件信息
     * @return 邮件信息
     */
    private EmailDO add(EmailVO email) {
        EmailDO emailDO = new EmailDO();
        emailDO.setEmail(email.getEmail());
        emailDO.setTitle(email.getTitle());
        emailDO.setContent(email.getContent());
        emailDO.setType(email.getTitle());
        //默认假设成功
        emailDO.setSuccess(email.getSuccess());
        emailDO.setLastSend(DateUtil.getDateline());
        emailDO.setErrorNum(email.getErrorNum());
        this.systemDaoSupport.insert(emailDO);
        return emailDO;
    }

    @Override
    public void sendMQ(EmailVO emailVO) {
        this.amqpTemplate.convertAndSend(AmqpExchange.EMAIL_SEND_MESSAGE, "emailSendMessageMsg", emailVO);
    }



    @Override
    public void sendEmail(EmailVO emailVO) {
        //获取当钱的smtp服务器
        SmtpDO smtp = smtpManager.getCurrentSmtp();

        debugger.log("找到smtp服务器：",smtp.toString());
        //根据对ssl的支付 分别走不同的发送方法
        if (smtp.getOpenSsl() == 1 || "smtp.qq.com".equals(smtp.getHost())) {
            debugger.log("使用ssl");
            this.sendMailByTransport(smtp, emailVO);
        } else {
            debugger.log("不使用ssl");

            this.sendMailByMailSender(smtp, emailVO);
        }
    }
}
